from typing import Dict, List, Optional, Union
from concurrent.futures import ThreadPoolExecutor
from datetime import datetime
from . import douyin, bilibili, xiaohongshu
from ..utils.logger import logger
from ..utils.config import config

class PublishResult:
    def __init__(self, platform: str, success: bool, message: str = ""):
        self.platform = platform
        self.success = success
        self.message = message
        self.timestamp = datetime.now()

class PlatformManager:
    def __init__(self):
        self._platforms = {
            'douyin': douyin,
            'bilibili': bilibili,
            'xiaohongshu': xiaohongshu
        }
        self._initialized_platforms = set()
        self._executor = ThreadPoolExecutor(
            max_workers=config.get('system.max_threads', 4)
        )
        self._callbacks = []

    def initialize_platform(self, platform: str) -> bool:
        """初始化指定平台"""
        try:
            if platform not in self._platforms:
                raise ValueError(f"不支持的平台: {platform}")

            if platform in self._initialized_platforms:
                return True

            # 检查平台是否启用
            if not config.get(f'platforms.{platform}.enabled', True):
                logger.info(f"平台 {platform} 已禁用")
                return False

            # 登录平台
            platform_module = self._platforms[platform]
            if platform_module.login():
                self._initialized_platforms.add(platform)
                logger.info(f"平台 {platform} 初始化成功")
                return True
            else:
                logger.error(f"平台 {platform} 初始化失败")
                return False

        except Exception as e:
            logger.error(f"初始化平台 {platform} 失败: {str(e)}")
            return False

    def publish_video(self, video_path: str, platforms: List[str],
                     title: str, description: str = "", tags: List[str] = None,
                     **kwargs) -> List[PublishResult]:
        """发布视频到指定平台"""
        results = []
        futures = []

        try:
            # 检查并初始化平台
            for platform in platforms:
                if not self.initialize_platform(platform):
                    results.append(PublishResult(
                        platform=platform,
                        success=False,
                        message="平台初始化失败"
                    ))
                    continue

                # 提交发布任务
                future = self._executor.submit(
                    self._publish_to_platform,
                    platform, video_path, title, description, tags, kwargs
                )
                futures.append((platform, future))

            # 等待所有任务完成
            for platform, future in futures:
                try:
                    success, message = future.result()
                    results.append(PublishResult(
                        platform=platform,
                        success=success,
                        message=message
                    ))
                except Exception as e:
                    results.append(PublishResult(
                        platform=platform,
                        success=False,
                        message=str(e)
                    ))

            # 通知发布结果
            self._notify_publish_results(results)
            return results

        except Exception as e:
            logger.error(f"发布视频失败: {str(e)}")
            return results

    def _publish_to_platform(self, platform: str, video_path: str,
                           title: str, description: str, tags: List[str],
                           extra_args: Dict) -> tuple:
        """发布视频到单个平台"""
        try:
            platform_module = self._platforms[platform]
            
            # 准备平台特定的参数
            kwargs = {}
            
            if platform == 'bilibili':
                kwargs['tid'] = extra_args.get('bilibili_tid', 21)
                kwargs['cover_path'] = extra_args.get('cover_path')
                
            elif platform == 'xiaohongshu':
                kwargs['topics'] = extra_args.get('topics', [])
                kwargs['location'] = extra_args.get('location')

            # 执行发布
            if platform_module.upload_video(
                video_path=video_path,
                title=title,
                description=description,
                tags=tags,
                **kwargs
            ):
                return True, "发布成功"
            else:
                return False, "发布失败"

        except Exception as e:
            logger.error(f"在平台 {platform} 发布失败: {str(e)}")
            return False, str(e)

    def register_callback(self, callback):
        """注册发布结果回调函数"""
        self._callbacks.append(callback)

    def _notify_publish_results(self, results: List[PublishResult]):
        """通知发布结果"""
        for callback in self._callbacks:
            try:
                callback(results)
            except Exception as e:
                logger.error(f"执行发布结果回调失败: {str(e)}")

    def close(self):
        """关闭所有平台连接"""
        try:
            for platform in self._initialized_platforms:
                try:
                    self._platforms[platform].close()
                except Exception as e:
                    logger.error(f"关闭平台 {platform} 失败: {str(e)}")
            
            self._initialized_platforms.clear()
            self._executor.shutdown()
            logger.info("所有平台已关闭")
            
        except Exception as e:
            logger.error(f"关闭平台管理器失败: {str(e)}")

    def __del__(self):
        """析构函数"""
        self.close()

# 创建全局平台管理器实例
platform_manager = PlatformManager()

# 导出便捷函数
def publish_video(video_path: str, platforms: List[str],
                 title: str, description: str = "", tags: List[str] = None,
                 **kwargs) -> List[PublishResult]:
    return platform_manager.publish_video(
        video_path, platforms, title, description, tags, **kwargs
    )

def initialize_platform(platform: str) -> bool:
    return platform_manager.initialize_platform(platform)

def register_callback(callback):
    platform_manager.register_callback(callback)

def close():
    platform_manager.close()
# 使platforms成为一个包
